package com.xufx.thread.liaoxuefeng.thread10_condition;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by xufx on 2022/1/4 23:11
 * 使用ReentrantLock比直接使用synhronized更安全，可以替代synchronized进行线程同步
 * synchronized配合wait和notify方法能够实现条件不满足时等待，条件满足时唤醒的功能。
 * 相对于synchronized的wait和notify方法，ReentrantLock可以使用Condition对象的wait和notify功能
 * 1.使用Condition时，引用的Condition对象必须从Lock实例的newCondition获取，这样才能获得绑定了Lock示例的Condition实例
 * 2. Condition提供的await(),signal(),signalAll()在原理上和synchronized锁对象的wait(),notify(),notifyAll()一致，行为也是一样的
 *      1. await()会释放当前锁，进入等待状态
 *      2. signal()会唤醒某个等待线程
 *      3. signalAll()会唤醒所有等待线程
 *      4. 唤醒线程await()返回后需要重新获得锁
 */
public class Main {
}

class TaskQueue{
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private Queue<String> queue = new LinkedList<>();

    public void addTask(String s){
        // 加锁
        lock.lock();
        try {
            queue.add(s);
            condition.signalAll();
        }finally {
            lock.unlock();
        }
    }

    public String getTask() throws InterruptedException {
        lock.lock();
        try {
            while(queue.isEmpty()){
                condition.await();
            }
            return queue.remove();
        } finally {
            lock.unlock();
        }
    }
}
